package gdbc

import (
	"fmt"
	_ "gdbc/github.com/go-sql-driver/mysql"
	"database/sql"
	"frame/utils/PropertiesUtils"
	"strconv"
	"time"
	"frame/logger/HLogger"
	"sync"
)

var logger = HLogger.GetHLogger("gdbc")

func getDriverName(gdbcname string)(string){
	result,_:=PropertiesUtils.GetConfig("gdbc",gdbcname+"driver","mysql")
	return result
}

func getDataSourceName(gdbcname string)(string){
	result,_:=PropertiesUtils.GetConfig("gdbc",gdbcname+"datasource","gzh:gzh@tcp(localhost:3306)/gzh?charset=utf8")
	return result
}

func getConnMaxLifetime(gdbcname string)(int){
	result_s,_ :=PropertiesUtils.GetConfig("gdbc",gdbcname+"connmaxlifetime","60")
	result_i,err2 :=strconv.Atoi(result_s)
	if(err2!=nil){
		logger.Error("初始化数据库连接[gdbc]["+gdbcname+"connmaxlifetime]格式错误，必须为整数int，单位为秒，默认值60")
		panic(err2)
	}
	return result_i
}
func getMaxOpenConns(gdbcname string)(int){
	result_s,_ :=PropertiesUtils.GetConfig("gdbc",gdbcname+"maxopenconns","100")
	result_i,err2 :=strconv.Atoi(result_s)
	if(err2!=nil){
		logger.Error("初始化数据库连接[gdbc]["+gdbcname+"maxopenconns]格式错误，必须为整数int，默认值100")
		panic(err2)
	}
	return result_i
}
func getMaxIdleConns(gdbcname string)(int){
	result_s,_ :=PropertiesUtils.GetConfig("gdbc",gdbcname+"maxidleconns","50")
	result_i,err2 :=strconv.Atoi(result_s)
	if(err2!=nil){
		logger.Error("初始化数据库连接[gdbc]["+gdbcname+"maxidleconns]格式错误，必须为整数int，默认值50")
		panic(err2)
	}
	return result_i
}
func getValidationQuery(gdbcname string)(string){
	result,_:=PropertiesUtils.GetConfig("gdbc",gdbcname+"validationquery","select 2")
	return result
}

var dbSourceMap map[string]*sql.DB = make(map[string]*sql.DB)

var DBSource_DefaultGdbcName = "default"

var mutex sync.Mutex

func GetDB(gdbcname string)(*sql.DB){
	var db *sql.DB
	var found bool
	var err error
	if db,found =dbSourceMap[gdbcname];!found {//第一次检查
		mutex.Lock()
		if db,found =dbSourceMap[gdbcname];!found {//加锁后第二次检查
		//保证DB只OPEN一次
			db, err = sql.Open(getDriverName(DBSource_DefaultGdbcName), getDataSourceName(DBSource_DefaultGdbcName))
			db.SetConnMaxLifetime(time.Duration(getConnMaxLifetime(DBSource_DefaultGdbcName)))//单位为秒
			db.SetMaxOpenConns(getMaxOpenConns(DBSource_DefaultGdbcName))
			db.SetMaxIdleConns(getMaxIdleConns(DBSource_DefaultGdbcName))
			if(err!=nil){
				logger.Error("数据库gdbcname["+gdbcname+"]创建链接失败，失败信息["+err.Error()+"]")
				panic(err)
			}else{
				err = db.Ping()
				if(err!=nil){
					logger.Error("数据库gdbcname["+gdbcname+"]创建链接失败，失败信息["+err.Error()+"]")
					panic(err)
				}else{
					logger.Info("数据库gdbcname["+gdbcname+"]创建链接成功")
				}
			}
			dbSourceMap[gdbcname]=db
		}
		mutex.Unlock()
	}
	logger.Debug("从dbSourceMap连接池中获取数据库gdbcname["+gdbcname+"]成功")
	return  db
}

func GetDefaultGdbcDB()(*sql.DB){
	return GetDB(DBSource_DefaultGdbcName)
}

func CloseDB(gdbcname string){
	var db *sql.DB
	var found bool
	if db,found =dbSourceMap[gdbcname];found {
		if(db!=nil){
			db.Close()
			logger.Debug("从dbSourceMap连接池中关闭数据库gdbcname["+gdbcname+"]成功")
			delete(dbSourceMap,gdbcname)
		}
	}
}
func CloseDefaultGdbcDB(){
	CloseDB(DBSource_DefaultGdbcName)
}


//go get github.com/go-sql-driver/mysql
//go install github.com/go-sql-driver/mysql
func Access(){
	fmt.Println("11111111111111111")
	db := GetDefaultGdbcDB()
	rows, err :=db.Query("select * from tbl_sys_dic")
	if(err!=nil){
		fmt.Println("访问失败"+err.Error())
	}
	for rows.Next() {
		columns,_  := rows.Columns()
		fmt.Println(columns)
		columnTypes,_  := rows.ColumnTypes()
		for _,ct := range columnTypes{
			fmt.Print(ct.DatabaseTypeName()+" ")
		}
		fmt.Print("\r\n")
		for _,ct := range columnTypes{
			fmt.Print(ct.ScanType().Name()+" ")
		}
		fmt.Print("\r\n")

		var id,code_idx,live_count int32
		var l1_code,l1_desc,l2_code,l2_desc,code_param,code_value,create_time,up_time string
		rows.Scan(&id,&l1_code,&l1_desc,&l2_code,&l2_desc,&code_param,&code_value,&code_idx,&live_count,&create_time,&up_time)
		fmt.Println(id,l1_code,l1_desc,l2_code,l2_desc,code_param,code_value,code_idx,live_count,create_time,up_time);
		fmt.Print("\r\n")
	}
	rows.Close()
	db.Close()
}
